import { browser } from 'webextension-polyfill-ts';
import {
    proxyStatus,
    notifications,
    restProxyStauts,
    closeProxyStauts,
    sendEmail,
    login,
    loginConnect,
    createProxy,
    closeProxy,
    getNodes,
    syncNodesCreateProxy,
    localNodesCreateProxy,
    logout,
    buy,
} from './utils';

import { v4 as uuidv4 } from 'uuid';
import { createWebsocket } from './ws';
import { isChrome } from '../utils';

let created = false;
browser.runtime.onInstalled.addListener(function () {
    proxyStatus();
    browser.storage.local.get('deviceId').then((result) => {
        if (!result.deviceId) {
            const uuid = uuidv4();
            browser.storage.local.set({ deviceId: uuid });
        }
    });
});

setTimeout(() => {
    if (!created) {
        browser.storage.local.get('deviceId').then((result) => {
            let deviceId = result.deviceId;
            if (!result.deviceId) {
                deviceId = uuidv4();
                browser.storage.local.set({ deviceId: deviceId });
            }
            localStorage.ClientIdent = deviceId;
            createWebsocket();
            created = true;
        });
    }
}, 0);

if (isChrome()) {
    browser.proxy.onProxyError.addListener(function (e) {
        proxyErroy(e);
    });
} else {
    browser.proxy.onError.addListener(function (e) {
        proxyErroy(e);
    });
}

const messageFunc: any = {
    createProxy,
    sendEmail,
    login,
    logout,
    loginConnect,
    getNodes,
    syncNodesCreateProxy,
    localNodesCreateProxy,
    closeProxy,
    buy,
};

browser.runtime.onMessage.addListener(function (message) {
    return new Promise((resovle) => {
        messageFunc[message.func](message.data)
            .then((e: any) => {
                resovle([e, true]);
            })
            .catch((e: any) => {
                resovle([e, false]);
            });
    });
});

function proxyErroy(e: any) {
    if (e.error === 'net::ERR_PROXY_CONNECTION_FAILED') {
        restProxyStauts().then((res) => {
            if (!res) {
                closeProxyStauts('代理服务器出现问题，当前节点不可用');
            }
        });
    }
}

let LoginSession: any = '';

browser.storage.local.get('LoginResult').then((result) => {
    if (result.LoginResult) {
        const session = result.LoginResult.LoginSession;
        if (session) {
            LoginSession = session;
        }
    }
});

function authCredentials() {
    return {
        authCredentials: {
            username: LoginSession.slice(0, 16),
            password: LoginSession.slice(16),
        },
    };
}

function onChanges(changes: any) {
    if (changes.LoginResult) {
        const { newValue } = changes.LoginResult;
        LoginSession = newValue.LoginSession;
    }
}

function credentialsToHeader(details: any) {
    if (!LoginSession) {
        return { requestHeaders: details.requestHeaders };
    }

    const requestHeaders = details.requestHeaders.filter(
        (header: any) => header.name !== 'Proxy-Authorization'
    );

    requestHeaders.push({
        name: 'Proxy-Authorization',
        value:
            'Basic ' +
            btoa(LoginSession.slice(0, 16) + ':' + LoginSession.slice(16)),
    });

    return { requestHeaders };
}

browser.storage.onChanged.addListener(onChanges);

if (browser.webRequest.onAuthRequired) {
    browser.webRequest.onAuthRequired.addListener(
        authCredentials,
        { urls: ['<all_urls>'] },
        ['blocking']
    );
} else {
    browser.webRequest.onBeforeSendHeaders.addListener(
        credentialsToHeader,
        { urls: ['<all_urls>'] },
        ['blocking', 'requestHeaders']
    );
}

browser.proxy.settings.onChange.addListener(function (details) {
    if (details.levelOfControl === 'controlled_by_other_extensions') {
        notifications(
            '其他应用正在控制代理设置。请禁用或者卸载发生冲突的应用。 如果不解决以上问题，则无法使用菠萝VPN'
        );
        closeProxy();
    }
});
